/**
 * 
 */
package com.example.timecodecalc;

/**
 * @author maxl
 *
 */

public  class Timecode {
	
	 
	static String str; // Строка для выввода через двоеточие
	static String strtime; // Представление таймкода ввиде строки
	int digit; // Переменная для хранения фреймов,секунд, минут, часов, дней, месяцев, годов
	int maxofdigit; // Максимальное значение переменной 
	int divider; // Делитель текущего разряда для получения значения из общего числа фреймов
	Timecode prev; // Ссылка на предыдущий объект класса Digit
	Timecode next; // Ссылка на следующий объект класса Digit
	
	class Digit extends Timecode{
				Digit(int max)
				{
					maxofdigit=max;
					digit=0;
					prev=Timecode.this; // Запоминаем ссылку предыдущий экземпляр класса Digit
					
				}
				
	};
	/**
	 * 
	 */
	public Timecode() {
		// TODO Auto-generated constructor stub
		digit=0;
		maxofdigit=0;
		str="";
		strtime="";	
	
	};
	// Создаем объекты и заполняем максимальные значения
	public Timecode  Create(int...args)
	{
		Timecode lastobject=null;
		Timecode prev=this;
		
		switch(args.length)
		{
		case 0:
			return null;
		case 1:
			this.maxofdigit=args[0];
			this.divider=maxofdigit;
			this.next=null;
			return this;
		default:
			this.maxofdigit=args[0];
		for(int i=1;i<args.length || lastobject==null;i++)
		{		
			lastobject=(i==1)?new Digit(args[i]):lastobject.new Digit(args[i]);
			prev.next=lastobject;
			prev=lastobject;
		}
		
		return lastobject;
			
		}

	}
	
	
	// Создаем объекты и заполняем максимальные значения для представления аргументов ввиде символьного массива целых чисел
	// Если невозможно преобразовать строку с целое возвращаем null
		public Timecode  Create(String args[])
		{
			Timecode lastobject=null;
			Timecode prev=this;
		
			switch(args.length)
			{
			case 0:
				return null;
			case 1:
				this.maxofdigit=Integer.valueOf(args[0]);
				this.divider=maxofdigit;
				this.next=null;
				if(Integer.valueOf(args[0])==null)
					return null;
				return this;
			default:
				this.maxofdigit=Integer.valueOf(args[0]);
				if(Integer.valueOf(args[0])==null)
					return null;
			for(int i=1;i<args.length || lastobject==null;i++)
			{		
				if(Integer.valueOf(args[i])==null)
					return null;
				lastobject=(i==1)?new Digit(Integer.valueOf(args[i])):lastobject.new Digit(Integer.valueOf(args[i]));
				prev.next=lastobject;
				prev=lastobject;
			}
			
			return lastobject;
				
			}

		}
	// Установка значений таймкода согласно ранее созданной в Create
	// последовательности разрядов
	
		public Timecode setDigit(int...newvalue){
			
			Timecode tmtc=this;
			int i=newvalue.length;
			if(i==0)
				return this;
			i--;
			while(tmtc.prev!=null)
			{
	 			tmtc.digit=newvalue[i--];
				tmtc=tmtc.prev;
				
			}
			tmtc.digit=newvalue[0];
			return this;
				
		}

	// Печатаем через двоеточия все разряды
	public Timecode prntwodot(Timecode end,int position)
	{
		int a,d,count;
		String tmp="";
		str="";
		// Если разрядов больше одного
		if(this.prev!=null)
				this.prev.prntwodot(end,position);
			a=digit;
			count=1;
			if(maxofdigit >=1)
			// Выдаем каждый знак в зависимости от колличества разрядов целое от деления на 10
			while(count<maxofdigit)
			{
					d=a%10; // Последняя цифра десятичного числа
					tmp=String.valueOf(d)+tmp;
					a=(a-d)/10; // Оставшиеся разряды
					count*=10;
			}
			
			str=str+tmp+((this!=end)?":":""); //Если последний знак не выдаем двоеточие
			//Spannable text = new SpannableString(str);
			//text.setSpan(new StyleSpan(Typeface.BOLD), str.length()-position, str.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
			
			return this;
	}
	// Печать таймкода во внутреннюю строковую переменную
	public Timecode prn()
	{
		int a,d,count;
		String tmp="";
		
		// Если разрядов больше одного
		if(this.prev!=null)
				this.prev.prn();
			a=digit;
			count=1;
			if(maxofdigit >=1)
			// Выдаем каждый знак в зависимости от колличества разрядов целое от деления на 10
			while(count<maxofdigit)
			{
					d=a%10; // Последняя цифра десятичного числа
					tmp=String.valueOf(d)+tmp;
					a=(a-d)/10; // Оставшиеся разряды
					count*=10;
			}
			
			strtime=strtime+tmp; //Если последний знак не выдаем двоеточие
			return this;
	}
}
// Расширяем возможности класса Timecode
// 
class Timecodes extends Timecode {
	boolean check; // Признак существования такого таймкода
	int positions; // Текущая позиция в таймкоде после авт. заполения нулями справа
	int maxdigits; // Максимальное количество десятичных цифр
	Timecode end; // ссылка на самый правый разряд
	Timecode first;// ссылка на самый левый разряд
	
	Timecodes(){
		check=false;
		positions=0;
		maxdigits=0;
	}
	// Задаем произвольный вид таймкода
	// Каждый разряд имеет максимальное значение 
	// после превышения которого на 1 увеличивается следующий за ним слева
public Timecode Creates(int...args){

	end=Create(args); // Создаем экземпляры разрядов
	first=this;
	// Вычисляем максимальное колличество символов
	for(int i=0;i < args.length;i++)
		maxdigits+=String.valueOf(args[i]).length();
	int tdivide=1;
	Timecode tmp; // Заполняем делители каждого разряда
	for(tmp=end;tmp!=null;tmp=tmp.prev)
	{
		tdivide*=tmp.maxofdigit;
		tmp.divider=tdivide;
	}
	return end;
}
public Timecode Creates(String args[]){

	end=Create(args); // Создаем экземпляры разрядов
	if(end==null)
		return null;
	first=this;
	// Вычисляем максимальное колличество символов
	for(int i=0;i < args.length;i++)
		maxdigits+=String.valueOf(args[i]).length();
	int tdivide=1;
	Timecode tmp; // Заполняем делители каждого разряда
	for(tmp=end;tmp!=null;tmp=tmp.prev)
	{
		tdivide*=tmp.maxofdigit;
		tmp.divider=tdivide;
	}
	return end;
}
public Timecode Clean(){

	Timecode tmp; 
	tmp=first;
	while(tmp!=null)
	{
		tmp=tmp.next;
		tmp.prev=null;
	}
	return null;
}
// Функция сдвигает влево и заполняет таймкод нулями справа если не бывает такого таймкода
// и запоминает позицию последнего нуля от введенного символа
public void AddZero(String tm,String checkchar)
{
	int counter=0;
	String temp=tm;
	
	check=true;
if(positions>0) //Таймкод возможен и позиция >0 и нет переполнения 
{
	// Если позиция ненулевая пытаемся добавить символ с текущей позиции
	temp=AddPosition(temp,checkchar,positions);
	TimecodeToFrames(temp);
	if(check)
		positions--; // Если все правильно увеличиваем позицию
}
else{
// Добавляем введенный символ справа
		// Если таймкод невозможен пытаемся добавить нули справа
		while(temp.substring(0,1).compareTo("0")==0)
		{
			temp=AddPosition(temp,"0",0);
			TimecodeToFrames(temp);
			if(check!=true)
			{
					counter++;
					check=true;
			}
			else
			{
				positions=++counter;
			break;
			}
		}
		
	}
		
}
// Добавляем нули слева и сдвигаем таймкод вправо до тех пор, когда 
// такой таймкод существует
	public String AddLeft(String tm,String chars) {
		String temps;
		temps=chars+tm;
		temps=temps.substring(0, temps.length()-1);
		if((temps.length()!=maxdigits) || chars.length()!=1)
		{ 
			check=false;
			return "";
		}
		check=true;
		TimecodeToFrames(temps);
		if(check==false && positions>0)
		{
			positions--;
		}
	
		return temps;
		
	}
	// Конвертирует из строкового представления таймкода в цифровой,записывает
	// его во внутренние переменные для каждого разряда и выдает результат в элементарных единицах.
	// Если такой таймкод не существует переменные не изменяются, а устанавливается
	// только check в false
	public int TimecodeToFrames(String stringtm) 
	{
		// Переводим значение таймкода из строкового значения в элементарные единицы
		// Количество разрядов и максимальное значение разрядов задается Creates
		Timecode tmp;
		int count,len,countmaxofdigit;
		int frames=0;
		int tt;
		
	
for(int i=0;i<2;i++)
{
	tmp=end;
	countmaxofdigit=1;
	count=maxdigits;
	frames=0;
		while(tmp.prev!=null)
		{
			len=String.valueOf(tmp.maxofdigit).length();
			String a=stringtm.substring(count-len,count);
			tt=Integer.valueOf(a);	
		if(tt>(tmp.maxofdigit-1))
		{
				check=false;
				return 0;
		}
			tmp.digit=(i==0)?tmp.digit:tt;	
			frames+=tmp.digit*countmaxofdigit;
			countmaxofdigit*=tmp.maxofdigit;
			tmp=tmp.prev;
			count-=len;
			
		}
		len=String.valueOf(tmp.maxofdigit).length();
		String a=stringtm.substring(count-len,count);
		tt=Integer.valueOf(a);
		if(tt>(tmp.maxofdigit-1))
		{
			check=false;
			return 0;
		}
		tmp.digit=(i==0)?tmp.digit:Integer.valueOf(a);
		
		frames+=tmp.digit*countmaxofdigit;
		
}		strtime="";
		end.prn();		
		return frames;
	}
	public String FramesToTimecode(int frames) 
	{
		// Перевод таймкода из элементарного количества фреймов в строку без двоеточия
		
		Timecode tmp=first;
		int rest;
		rest=frames;
		
		while(tmp.next!=null)
		{
			tmp.digit=rest/tmp.next.divider;
			rest=rest-(tmp.digit*tmp.next.divider);
			tmp=tmp.next;
		}
		tmp.digit=rest;
		//Toast.makeText(this, "Frames to Timecode " +dstr+":"+hstr+":"+mstr+":"+sstr+":"+fstr, Toast.LENGTH_LONG).show();
		strtime="";
		end.prn();
		return  strtime;
	}
	public String AddPosition(String tm,String chars,int Position)
	 {
		
		 String temp;
		 int lenstr=tm.length();
		 if((Position<0) || (Position >lenstr) || (tm.length()!=maxdigits) || (chars.length()!=1))
		 {
			 
			 check=false;
			 return tm;
		 }
		 if(Position==0)
			 temp=tm.substring(1, lenstr)+chars;
		 else
			 temp=tm.substring(0, lenstr-Position)+chars+tm.substring(lenstr-Position+1, lenstr);
		 if(temp.length()!=maxdigits)
		 {
			 check=false;
			 return tm;
		 }
		return temp;
		
	 }
}